package com.taiji.dicom4cloud.smart.camera;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.taiji.dicom4cloud.common.core.utils.DateUtil;
import com.taiji.dicom4cloud.common.core.utils.R;
import com.taiji.dicom4cloud.smart.config.CameraApi;
import com.taiji.dicom4cloud.smart.controller.AlarmRecordController;
import com.taiji.dicom4cloud.smart.model.entity.Camera;
import com.taiji.dicom4cloud.smart.model.entity.RfidRecord;
import com.taiji.dicom4cloud.smart.rfid.config.MqttGatewayService;
import com.taiji.dicom4cloud.smart.service.AlarmRecordService;
import com.taiji.dicom4cloud.smart.service.CameraEquipmentService;
import com.taiji.dicom4cloud.smart.service.SysConfigService;
import com.taiji.dicom4cloud.smart.utils.FtpUtil;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

/**
 * 接收摄像头回调
 */
@RestController
@RequestMapping("/camera" )
@Slf4j
public class CameraHandler {


    @Autowired
    private AlarmRecordService alarmRecordService;

    @Autowired
    private MqttGatewayService mqttGatewayService;

    @Autowired
    private CameraEquipmentService cameraEquipmentService;

    @Autowired
    private AsyncTaskService asyncTaskService;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private FtpUtil ftpUtil;

    /**
     * 接收大华云平台摄像头消息回调
     * @param msg
     * @return
     */
    @PostMapping("/camera")
    public R getCameraData(@RequestBody JSONObject msg){
        log.info("大华消息接受");
        log.info(msg.toString());
        return R.ok(this.saveCameraData(msg));
    }

    @PostMapping("/hls")
    public R getVideoHlsUrl(@RequestBody JSONObject msg){
        String deviceId = msg.getString("deviceId");
        String channelId =  msg.getString("channelId");
        String beginTime =  msg.getString("beginTime");
        String endTime =  msg.getString("endTime");
        String alarmId = msg.getString("id");

        JSONObject jsonObject = new JSONObject();
        RfidRecord record = alarmRecordService.getById(alarmId);
        if(ObjectUtil.isNotNull(record)&&!StrUtil.isEmpty(record.getCameraHlsUrl())){
            jsonObject.put("url",record.getCameraCaptureUrl());
            return R.ok(jsonObject);
        }else{
            Map<String, Object> map = sysConfigService.getConfigByKeys("client_id,client_secret");
            String token = CameraApi.getToken(String.valueOf(map.get("client_id")),String.valueOf(map.get("client_secret")));
            JSONObject jsonObject2 = CameraApi.createDeviceRecordHls(deviceId,channelId,beginTime,endTime,token);
            //保存hls地址
            if(jsonObject2.getBoolean("success")){
                if(ObjectUtil.isNotNull(record)){
                    record.setCameraHlsUrl(jsonObject2.getJSONObject("data").getString("url"));
                    jsonObject.put("url",jsonObject2.getJSONObject("data").getString("url"));
                    alarmRecordService.saveOrUpdate(record);
                }
            }else{
                jsonObject.put("errMsg",jsonObject2.getString("errMsg"));
            }
            return R.ok(jsonObject);
        }
    }

    public Boolean saveCameraData(JSONObject msg) {
        if(ObjectUtil.isNotNull(msg)){
            Map<String, Object> map = sysConfigService.getConfigByKeys("use_dh_cloud");
            //走大华云平台回调方式
            if(Integer.parseInt(map.get("use_dh_cloud").toString())==0){
                JSONObject jsonObject = msg;
                String msgType = jsonObject.getString("msgType");
                String messageId = jsonObject.getString("messageId");
                Long time = jsonObject.getLong("time");///时间毫秒
                String deviceId = jsonObject.getString("deviceId");
                RfidRecord record = new RfidRecord();

                Camera camera = cameraEquipmentService.getOne(Wrappers.<Camera>lambdaQuery().eq(Camera::getDeviceId,deviceId));
                if(ObjectUtil.isNotNull(camera)){
                    record.setOrgName(camera.getOrgName());
                    record.setOrgId(camera.getOrgId());
                    record.setLatitude(camera.getLatitude());
                    record.setLongitude(camera.getLongitude());
                    record.setEquipmentName(camera.getCameraEquipmentName());
                    record.setEquipmentId(deviceId);

                }
                record.setAlarmTime(LocalDateTime.now());
                record.setAlarmName(msgType);
                record.setCameraMessageId(messageId);
                record.setType("2");
                record.setCreateTime(LocalDateTime.now());
                alarmRecordService.save(record);
                mqttGatewayService.send2Mqtt("alarm.rfid", JSONObject.toJSONString(record));
                log.info(record.getId().toString());
                //异步不阻塞
                CompletableFuture<String> future1 = asyncTaskService.capture2(deviceId);
                future1.whenComplete((result,e)->{
                    log.info("写入抓图地址：{},{}",result,record.getId().toString());
                    if(StrUtil.isNotEmpty(result)){
                        JSONObject jsonObject1 = JSONObject.parseObject(result);
                        record.setCameraCaptureUrl(jsonObject1.getString("url"));
                        alarmRecordService.saveOrUpdate(record);
                    }
                });


                //视频录制长度为一分钟
//            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//            LocalDateTime alarmTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(time-3*60*1000), ZoneId.of("+8"));
//            LocalDateTime alarmTime2 = LocalDateTime.ofInstant(Instant.ofEpochMilli(time+3*60*1000), ZoneId.of("+8"));
//            String beginTime = dateTimeFormatter.format(alarmTime);
//            String endTime = dateTimeFormatter.format(alarmTime2);
//
//            JSONObject jsonObject1 = new JSONObject();
//            jsonObject1.put("deviceId",deviceId);
//            jsonObject1.put("channelId","0");
//            jsonObject1.put("beginTime",beginTime);
//            jsonObject1.put("endTime",endTime);
//            log.info("HLS时间段：{},{}",beginTime,endTime);
//            CompletableFuture<String> future2 = asyncTaskService.createHls(jsonObject1);
//            future2.whenComplete((result,e)->{
//                log.info("写入HLS地址：{},{}",result,record.getId().toString());
//                if(StrUtil.isNotEmpty(result)){
//                    record.setCameraHlsUrl(result);
//                    alarmRecordService.saveOrUpdate(record);
//                }
//            });
            }
            log.info("大华回调入库成功");
        }

        return Boolean.TRUE;
    }

    @PostMapping("/video")
    public R downLoadVideo(){
        try {
            ftpUtil.makeDirectory(ftpUtil.getFtpClient(),"hxxx");
            boolean exists = ftpUtil.existFile(ftpUtil.getFtpClient(),"testfile.txt");
            if(exists){
                InputStream is = ftpUtil.downloadFile(ftpUtil.getFtpClient(),"7F0777FPAG66B09","adb操作步骤.txt");
                FileOutputStream fos = new FileOutputStream("00000000000.txt");
                byte[] b = new byte[1024];
                while ((is.read(b)) != -1) {
                    fos.write(b);// 写入数据
                }
                is.close();
                fos.close();// 保存数据
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.ok();
    }
}